# -*-coding: utf-8 -*-
"""
    @Theme   : Redis Client API
    @Time    : 2024/7/10 5:42
    @Author  : YamFish
    @Url     : https://www.zhihu.com/people/yamfish
"""
from typing import Generator

import redis


class RedisClient:
    def __init__(self, app=None, host='localhost', port=6379, password=None):
        if app:
            self.client = redis.Redis(host=app.config['REDIS_HOST'],
                                      port=app.config['REDIS_PORT'],
                                      password=app.config['REDIS_PASSWORD'],
                                      socket_timeout=120)
        else:
            self.client = redis.Redis(host=host, port=port, password=password)

    def hash_set(self, key, field, value):
        self.client.hset(key, field, value)

    def delete_key(self, key):
        self.client.delete(key)

    def delete_hash_key(self, key, field):
        self.client.hdel(key, field)

    def hash_get(self, key, field):
        return self.client.hget(key, field)

    def is_hash_field_exists(self, key, field):
        return self.client.hexists(key, field)

    def set_bit(self, key, offset, value):
        self.client.setbit(key, offset, value)

    def is_bit_set(self, key, offset):
        return self.client.getbit(key, offset) == 1

    def is_bit_list_set(self, key, offset_list: Generator) -> bool:
        for offset in offset_list:
            if not self.is_bit_set(key, offset):
                return False
        return True

    def set_str_if_not_exists(self, redis_key: str, value: int) -> bool:
        if self.client.set(redis_key, value, nx=True):
            return True
        return False

    def sorted_set_add(self, key, value, score):
        self.client.zadd(key, {value: score})

    def sorted_set_remove(self, key, value):
        self.client.zrem(key, value)

    def sorted_set_get_by_rank(self, key, rank_start, offset, with_scores=True):
        return self.client.zrevrange(key, rank_start, rank_start+offset, withscores=with_scores)

    def sorted_set_increase_score(self, key, target, value):
        self.client.zincrby(key, value, target)
